﻿/*   
    Copyright (C) 2009 Galaktika Corporation ZAO

    This file is a part of Galaktika.BusinessMonitor
 
    Galaktika.BusinessMonitor is a free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
      
    You should have received a copy of the GNU General Public License
    along with Galaktika.BusinessMonitor.  If not, see <http://www.gnu.org/licenses/>.
  
    If GPL v.3 is not suitable for your products or company,
    Galaktika Corp provides Galaktika.BusinessMonitor under a flexible commercial license
    designed to meet your specific usage and distribution requirements.
    If you have already obtained a commercial license from Galaktika Corp,
    you can use this file under those license terms.
*/

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Galaktika.BI.Extensibility;
using Galaktika.BI.Silverlight;
using Localization = Galaktika.BI.Addin.VisifireChart.Runtime.Localization;

namespace Galaktika.BI.Charting
{
    /// <summary>
    /// Класс, представляющий коллекцию "серий" контрола PivotChart
    /// </summary>
    public class ChartSeriesCollection : Collection<ChartSeries>, IModifiable
    {
        #region Constructor
        /// <summary>
        /// Конструктор - просто создает коллекцию
        /// </summary>
        public ChartSeriesCollection()
            : base()
        {
        }
        #endregion Constructor

        #region Properies
        private bool m_IsEmpty = true;
        /// <summary>
        /// Пустая ли коллекция
        /// </summary>
        public bool IsEmpty
        {
            get
            {
                return m_IsEmpty;
            }
        }

        /// <summary>
        /// Возвращает элемент коллекции с индексом index
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public ChartSeries this[int index]
        {
            get
            {
                if ((index >= 0) && (index < this.Count))
                    return (ChartSeries)base.Items[index];
                else
                    return null;
            }
        }

        private string m_NamePrefix = "Series ";
        private string NamePrefix
        {
            get
            {
                return m_NamePrefix;
            }
        }
        #endregion Properies

        #region Public Methods

        public void Assign(ChartSeriesCollection collection)
        {
            if (collection == null)
            {
                throw new ArgumentNullException("collection");
            }
            base.Items.Clear();
            foreach (ChartSeries element in collection)
            {
                ChartSeries item = (ChartSeries)element.Clone();
                base.Items.Add(item);
            }
            this.m_IsEmpty = false;
        }

        /// <summary>
        /// Добавляет серию в конец коллекции
        /// </summary>
        /// <param name="series"></param>
        public void Add(ChartSeries series)
        {
            base.Items.Add(series);
            this.m_IsEmpty = false;
        }

        /// <summary>
        /// Добавляет массив серий в конец коллекции
        /// </summary>
         public void AddRange(ChartSeries[] seriesArray)
        {
            foreach (var series in seriesArray)
            {
                base.Items.Add(series);
            }
            //base.Items.AddRange(seriesArray);
            this.m_IsEmpty = false;
        }

        /// <summary>
        /// Удаляет из коллекции серию series
        /// </summary>
        /// <param name="series"></param>

        public void Remove(ChartSeries series)
        {
            base.Items.Remove(series);
            if (base.Items.Count == 0)
                this.m_IsEmpty = true;
        }

        /// <summary>
        /// Удаляет из коллекции серию c индексом index
        /// </summary>
        /// <param name="index"></param>
        public void Remove(int index)
        {
            base.Items.RemoveAt(index);
            if (base.Items.Count == 0)
                this.m_IsEmpty = true;
        }

        /// <summary>
        /// Копирует существующую коллекцию в массив seriesArray
        /// </summary>
        /// <param name="seriesArray"></param>
        public void CopyTo(ChartSeries[] seriesArray)
        {
            base.Items.CopyTo(seriesArray,0);
        }

        /// <summary>
        /// Копирует существующуюю коллекцию в массив seriesArray,
        /// начиная с индекса arrayIndex
        /// </summary>
        /// <param name="seriesArray"></param>
        public void CopyTo(ChartSeries[] seriesArray, int arrayIndex)
        {
            base.Items.CopyTo(seriesArray, arrayIndex);
        }

        /// <summary>
        /// Создает копию коллекции
        /// </summary>
        public ChartSeriesCollection Clone()
        {
            ChartSeriesCollection collectResult = new ChartSeriesCollection();
            foreach (ChartSeries element in this)
            {
                ChartSeries item = (ChartSeries)element.Clone();
                collectResult.Add(item);
            }

            return collectResult;
        }

        ///// <summary>
        ///// Создает массив элементов ChartSeries
        ///// </summary>      
        //public ChartSeries[] ToArray()
        //{
        //    return (ChartSeries[])base.Items.ToArray(typeof(ChartSeries));
        //}

        public void Swap(ChartSeries series1, ChartSeries series2)
        {
            if (series1 == null)
            {
                throw new ArgumentNullException("series1");
            }

            if (series2 == null)
            {
                throw new ArgumentNullException("series2");
            }

            int index1 = base.Items.IndexOf(series1);
            int index2 = base.Items.IndexOf(series2);
            if (index1 == -1)
            {
                throw new ArgumentException(Localization.Exc_IndexLessNull, "index1");
            }
            if (index2 == -1)
            {
                throw new ArgumentException(Localization.Exc_IndexLessNull, "index2");
            }
            this.Swap(index1, index2);
        }

        public void Swap(int index1, int index2)
        {
            if ((index1 < 0) || (index1 >= base.Count))
            {
                throw new ArgumentException(Localization.Exc_IndexOutOfRange, "index1");
            }
            if ((index2 < 0) || (index2 >= base.Count))
            {
                throw new ArgumentException(Localization.Exc_IndexOutOfRange, "index2");
            }

            ChartSeries _ChartSeries1 = (ChartSeries)base.Items[index1];
            ChartSeries _ChartSeries2 = (ChartSeries)base.Items[index2];
            base.Items.RemoveAt(index1);
            base.Items.Insert(index1, _ChartSeries2);
            base.Items.RemoveAt(index2);
            base.Items.Insert(index2, _ChartSeries1);
        }

        // Генерирует уникальное имя серии
        public string GenerateName()
        {
            List<string> usedNames = new List<string>(this.GetNames());

            for (int nameCounter = 1; nameCounter < 100; nameCounter++)
            {
                string uniqueName = this.NamePrefix + nameCounter.ToString();
                if (!usedNames.Contains(uniqueName))
                {
                    return uniqueName;
                }
            }

            return this.NamePrefix;
        }

        // Генерирует индекс серии
        public int GenerateSeriesIndex()
        {
            return base.Items.Count;
        }

        private string[] GetNames()
        {
            string[] strArray = new string[base.Count];
            for (int i = 0; i < base.Count; i++)
            {
                strArray[i] = this[i].AName;
            }
            return strArray;
        }

        public ChartSeries GetMasterSeries()
        {
            ChartSeries series = null;
            if ((this != null) && (this.Count > 0))
                series = this[0];

            return series;
        }
        #endregion Public Methods


        #region IModified Members

        public event ModifiedChangedEventHandler CollectionModified;

        public void RaiseCollectionModified(ModifiedChangedEventArgs e)
        {
            // вызов делегата через посредника EventHandler нужно для
            // безопасности в многопотоковом режиме
            ModifiedChangedEventHandler handler = CollectionModified;
            if (handler != null)
                handler(this, e);
        }

        #endregion  IModified Members
    }
}
